use dioxus::prelude::*;
use openssl::symm::{Cipher, Crypter, Mode};
use std::str;

use crate::components::copy::Copy;

#[derive(PartialEq, Clone, Copy)]
enum AesMode {
    Cbc,
    Ecb,
    Ctr,
}

#[derive(PartialEq, Clone, Copy)]
enum AesKeySize {
    Aes128,
    Aes256,
}

#[component]
pub fn AesEnDecryptor() -> Element {
    let mut input_text = use_signal(|| String::new());
    let mut key = use_signal(|| String::new());
    let mut iv = use_signal(|| String::new());
    let mut aes_mode = use_signal(|| AesMode::Cbc);
    let mut key_size = use_signal(|| AesKeySize::Aes256);
    let mut output_text = use_signal(|| String::new());
    let mut is_encrypt = use_signal(|| true);
    let mut copy_status = use_signal(|| String::new());

    // 执行加密/解密
    let perform_crypto = move |_| {
        let cipher = match (*aes_mode.read(), *key_size.read()) {
            (AesMode::Cbc, AesKeySize::Aes128) => Cipher::aes_128_cbc(),
            (AesMode::Cbc, AesKeySize::Aes256) => Cipher::aes_256_cbc(),
            (AesMode::Ecb, AesKeySize::Aes128) => Cipher::aes_128_ecb(),
            (AesMode::Ecb, AesKeySize::Aes256) => Cipher::aes_256_ecb(),
            (AesMode::Ctr, AesKeySize::Aes128) => Cipher::aes_128_ctr(),
            (AesMode::Ctr, AesKeySize::Aes256) => Cipher::aes_256_ctr(),
        };

        let result = if *is_encrypt.read() {
            encrypt(
                &input_text.read(),
                &key.read(),
                &iv.read(),
                cipher,
                *key_size.read(),
            )
        } else {
            decrypt(
                &input_text.read(),
                &key.read(),
                &iv.read(),
                cipher,
                *key_size.read(),
            )
        };

        output_text.set(result.unwrap_or_else(|e| format!("Error: {}", e)));
    };

    rsx! {
        div { class: "flex-1 flex flex-col",
            div { class: "flex-1 p-8 overflow-auto",
                div { class: "max-w-4xl mx-auto space-y-6",
                    // 标题和描述
                    div { class: "space-y-2",
                        h1 { class: "text-2xl font-bold text-gray-900", "AES 加/解密工具" }
                        p { class: "text-gray-600", "支持 AES-128/AES-256 和 CBC/ECB/CTR 加/解密模式" }
                    }

                    // 输入卡片
                    div { class: "bg-white border border-gray-200 rounded-xl shadow-sm",
                        div { class: "p-6",
                            div { class: "space-y-4",
                                // 输入文本区域
                                div { class: "space-y-2",
                                    label { class: "block text-sm font-medium text-gray-700",
                                        if *is_encrypt.read() { "明文" } else { "密文 (Base64)" }
                                    }
                                    textarea {
                                        oninput: move |e| input_text.set(e.value()),
                                        value: "{input_text}",
                                        class: "w-full h-40 px-3 py-2 border border-gray-300 rounded-lg font-mono text-sm focus:ring-blue-500 focus:border-blue-500",
                                        placeholder: if *is_encrypt.read() {
                                            "输入要加密的文本"
                                        } else {
                                            "输入要解密的Base64密文"
                                        }
                                    }
                                }

                                // 密钥和IV输入区
                                div { class: "grid grid-cols-1 md:grid-cols-2 gap-4",
                                    div { class: "space-y-2",
                                        label { class: "block text-sm font-medium text-gray-700",
                                            match *key_size.read() {
                                                AesKeySize::Aes128 => "密钥 (16字节)",
                                                AesKeySize::Aes256 => "密钥 (32字节)",
                                            }
                                        }
                                        input {
                                            r#type: "text",
                                            oninput: move |e| key.set(e.value()),
                                            value: "{key}",
                                            class: " block w-full
                                                                       px-3 py-2  // 调整内边距
                                                                       text-sm text-gray-900  // 文字颜色
                                                                       bg-white  // 背景色
                                                                       border border-gray-300  // 边框
                                                                       rounded-lg  // 更大的圆角
                                                                       shadow-sm  // 轻微阴影
                                                                       focus:outline-none  // 移除默认轮廓
                                                                       focus:ring-2 focus:ring-blue-500  // 聚焦光环效果
                                                                       focus:border-blue-500  // 聚焦边框色
                                                                       hover:border-gray-400  // 悬停效果
                                                                       transition-colors  // 颜色过渡动画
                                                                       appearance-none  // 移除原生样式
                                                                       [&::-webkit-inner-spin-button]:appearance-none  // 隐藏旋转按钮(Webkit)
                                                                       [&::-webkit-outer-spin-button]:appearance-none  // 隐藏旋转按钮(Webkit)",
                                            placeholder: match *key_size.read() {
                                                AesKeySize::Aes128 => "输入16字节密钥",
                                                AesKeySize::Aes256 => "输入32字节密钥",
                                            }
                                        }
                                    }

                                    // IV输入 (CBC和CTR模式需要)
                                    if *aes_mode.read() != AesMode::Ecb {
                                        div { class: "space-y-2",
                                            label { class: "block text-sm font-medium text-gray-700", "IV (16字节)" }
                                            input {
                                                r#type: "text",
                                                oninput: move |e| iv.set(e.value()),
                                                value: "{iv}",
                                                class: " block w-full
                                                                           px-3 py-2  // 调整内边距
                                                                           text-sm text-gray-900  // 文字颜色
                                                                           bg-white  // 背景色
                                                                           border border-gray-300  // 边框
                                                                           rounded-lg  // 更大的圆角
                                                                           shadow-sm  // 轻微阴影
                                                                           focus:outline-none  // 移除默认轮廓
                                                                           focus:ring-2 focus:ring-blue-500  // 聚焦光环效果
                                                                           focus:border-blue-500  // 聚焦边框色
                                                                           hover:border-gray-400  // 悬停效果
                                                                           transition-colors  // 颜色过渡动画
                                                                           appearance-none  // 移除原生样式
                                                                           [&::-webkit-inner-spin-button]:appearance-none  // 隐藏旋转按钮(Webkit)
                                                                           [&::-webkit-outer-spin-button]:appearance-none  // 隐藏旋转按钮(Webkit)",
                                                placeholder: "输入16字节IV"
                                            }
                                        }
                                    }
                                }

                                // 加密模式、密钥长度和操作区
                                div { class: "grid grid-cols-1 md:grid-cols-4 gap-4",
                                    // 加密模式选择
                                    div { class: "space-y-2",
                                        label { class: "block text-sm font-medium text-gray-700", "加密模式" }
                                        select {
                                            onchange: move |e| {
                                                aes_mode.set(match e.value().as_str() {
                                                    "ECB" => AesMode::Ecb,
                                                    "CTR" => AesMode::Ctr,
                                                    _ => AesMode::Cbc,
                                                });
                                            },
                                            value: match *aes_mode.read() {
                                                AesMode::Cbc => "CBC",
                                                AesMode::Ecb => "ECB",
                                                AesMode::Ctr => "CTR",
                                            },
                                            class: " w-full
                                            px-4 py-2
                                            text-sm text-gray-800
                                            bg-white
                                            border border-gray-300
                                            rounded-lg
                                            shadow-sm
                                            transition-all
                                            focus:outline-none
                                            focus:ring-2 focus:ring-blue-500
                                            focus:border-blue-500
                                            hover:border-gray-400
                                            cursor-pointer
                                            appearance-none",
                                            option { value: "CBC", "CBC (推荐)" }
                                            option { value: "ECB", "ECB" }
                                            option { value: "CTR", "CTR" }
                                        }
                                    }

                                    // 密钥长度选择
                                    div { class: "space-y-2",
                                        label { class: "block text-sm font-medium text-gray-700", "密钥长度" }
                                        select {
                                            onchange: move |e| {
                                                key_size.set(match e.value().as_str() {
                                                    "128" => AesKeySize::Aes128,
                                                    _ => AesKeySize::Aes256,
                                                });
                                            },
                                            value: match *key_size.read() {
                                                AesKeySize::Aes128 => "128",
                                                AesKeySize::Aes256 => "256",
                                            },
                                            class: " w-full
                                            px-4 py-2
                                            text-sm text-gray-800
                                            bg-white
                                            border border-gray-300
                                            rounded-lg
                                            shadow-sm
                                            transition-all
                                            focus:outline-none
                                            focus:ring-2 focus:ring-blue-500
                                            focus:border-blue-500
                                            hover:border-gray-400
                                            cursor-pointer
                                            appearance-none",
                                            option { value: "128", "AES-128" }
                                            option { value: "256", "AES-256" }
                                        }
                                    }

                                    // 加密/解密切换
                                    div { class: "space-y-2",
                                        label { class: "block text-sm font-medium text-gray-700", "操作类型" }
                                        select {
                                            onchange: move |e| is_encrypt.set(e.value() == "encrypt"),
                                            value: if *is_encrypt.read() { "encrypt" } else { "decrypt" },
                                            class: " w-full
                                            px-4 py-2
                                            text-sm text-gray-800
                                            bg-white
                                            border border-gray-300
                                            rounded-lg
                                            shadow-sm
                                            transition-all
                                            focus:outline-none
                                            focus:ring-2 focus:ring-blue-500
                                            focus:border-blue-500
                                            hover:border-gray-400
                                            cursor-pointer
                                            appearance-none",
                                            option { value: "encrypt", "加密" }
                                            option { value: "decrypt", "解密" }
                                        }
                                    }

                                    // 执行按钮
                                    div { class: "flex items-end",
                                        button {
                                            onclick: perform_crypto,
                                            class: "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500",
                                            if *is_encrypt.read() { "加密" } else { "解密" }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // 结果卡片
                    if !output_text.read().is_empty() {
                        div { class: "bg-white border border-gray-200 rounded-xl shadow-sm",
                            div { class: "p-6",
                                div { class: "flex justify-between items-center mb-4",
                                    h2 { class: "text-lg font-semibold text-gray-900",
                                        if *is_encrypt.read() { "加密结果 (Base64)" } else { "解密结果" }
                                    }
                                    Copy{
                                        val:output_text.clone()
                                    }
                                }
                                div { class: "p-4 bg-gray-50 rounded-lg font-mono text-sm whitespace-pre-wrap overflow-x-auto",
                                    "{output_text}"
                                }

                            }
                        }
                    }
                }
            }
        }
    }
}

// 加密函数
fn encrypt(
    plaintext: &str,
    key: &str,
    iv: &str,
    cipher: Cipher,
    key_size: AesKeySize,
) -> Result<String, openssl::error::ErrorStack> {
    let required_len = match key_size {
        AesKeySize::Aes128 => 16,
        AesKeySize::Aes256 => 32,
    };
    let key = pad_key(key, required_len);
    let iv = pad_iv(iv, cipher.iv_len().unwrap_or(0));

    let mut crypter = Crypter::new(cipher, Mode::Encrypt, &key, iv.as_deref())?;
    crypter.pad(true);

    let mut ciphertext = vec![0; plaintext.len() + cipher.block_size()];
    let count = crypter.update(plaintext.as_bytes(), &mut ciphertext)?;
    let rest = crypter.finalize(&mut ciphertext[count..])?;
    ciphertext.truncate(count + rest);

    Ok(base64::encode(ciphertext))
}

// 解密函数
fn decrypt(
    ciphertext: &str,
    key: &str,
    iv: &str,
    cipher: Cipher,
    key_size: AesKeySize,
) -> Result<String, openssl::error::ErrorStack> {
    let ciphertext = base64::decode(ciphertext).map_err(|_| openssl::error::ErrorStack::get())?;

    let required_len = match key_size {
        AesKeySize::Aes128 => 16,
        AesKeySize::Aes256 => 32,
    };
    let key = pad_key(key, required_len);
    let iv = pad_iv(iv, cipher.iv_len().unwrap_or(0));

    let mut crypter = Crypter::new(cipher, Mode::Decrypt, &key, iv.as_deref())?;
    crypter.pad(true);

    let mut plaintext = vec![0; ciphertext.len() + cipher.block_size()];
    let count = crypter.update(&ciphertext, &mut plaintext)?;
    let rest = crypter.finalize(&mut plaintext[count..])?;
    plaintext.truncate(count + rest);

    String::from_utf8(plaintext).map_err(|_| openssl::error::ErrorStack::get())
}

// 密钥填充处理
fn pad_key(key: &str, required_len: usize) -> Vec<u8> {
    let mut key_bytes = key.as_bytes().to_vec();
    if key_bytes.len() < required_len {
        key_bytes.extend(vec![0; required_len - key_bytes.len()]);
    } else if key_bytes.len() > required_len {
        key_bytes.truncate(required_len);
    }
    key_bytes
}

// IV填充处理
fn pad_iv(iv: &str, required_len: usize) -> Option<Vec<u8>> {
    if required_len == 0 {
        return None;
    }

    let mut iv_bytes = iv.as_bytes().to_vec();
    if iv_bytes.len() < required_len {
        iv_bytes.extend(vec![0; required_len - iv_bytes.len()]);
    } else if iv_bytes.len() > required_len {
        iv_bytes.truncate(required_len);
    }
    Some(iv_bytes)
}
